package snapex.expense.controller;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import snapex.core.model.Expense;
import snapex.core.model.InvoiceImage;
import snapex.core.model.Result;
import snapex.core.model.SearchParams;
import snapex.expense.service.IExpenseService;
import snapex.expense.service.impl.ExpenseServiceProxy;
import snapex.invoice.service.IInvoiceService;

@Slf4j
@RestController
public class ImportController {
	@Autowired
	ExpenseServiceProxy expenseServiceProxy;
	
	@Autowired
	IExpenseService expenseService;
	
	@Autowired
	IInvoiceService invoiceService;
	
	@ApiOperation(value = "Import expenses and invoices")
	@PostMapping(value="/expense/importall", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public ResponseEntity importAll(SearchParams params) throws Exception{
				
		log.debug("***POST /expense/importall -> Start to export expense and invoice from Ali Cloud, params={}",params);
		
		byte[] expenseData = expenseServiceProxy.exportAll(params);
		
		log.debug("***Start to import expense and invoice into DRN, params={}",params);
		
		List<InvoiceImage> images = new ArrayList<InvoiceImage>();
		
		ZipInputStream zip = new ZipInputStream(new ByteArrayInputStream(expenseData));		
		
		ZipEntry entry = zip.getNextEntry();
		Result result = new Result();		
		while(entry != null) {
//			log.debug("entry.getName()={}", entry.getName());
			
			byte[] buffer = new byte[1024];
			ByteArrayOutputStream baos = new ByteArrayOutputStream();				
			int length = 0;
			while((length = zip.read(buffer)) != -1){
				baos.write(buffer, 0, length);
			}
			zip.closeEntry();
			
			if(entry.getName().endsWith(".json")) {				
				ObjectMapper MAPPER = new ObjectMapper();				
				Result<List<Expense>> expense = MAPPER.readValue(new ByteArrayInputStream(baos.toByteArray()), new TypeReference<Result<List<Expense>>>(){});				
				result = expenseService.importExpenses(expense.getData());				
			}else {				
				String entryName = entry.getName();
				String invoiceId = entryName.substring(entryName.lastIndexOf("/") + 1, entryName.indexOf("."));
				String mime = entryName.substring(entryName.indexOf(".") + 1);
//				log.debug("****invoiceId={}, mime={}",invoiceId, mime);
				InvoiceImage image = new InvoiceImage();
				image.setInvoiceId(invoiceId);
				image.setMime(mime);
				image.setImage(baos.toByteArray());
				images.add(image);
			}
			
			entry = zip.getNextEntry();
		}		
		
		if(!images.isEmpty()) {
			log.debug("***Start to import invoice images into DRN");
			try {
				invoiceService.importInvoiceImages(images);
			}
			catch(Exception e) {
				log.error("***Failed to import invoice images");
			}
		}
		return ResponseEntity.ok(result);		
	}
	
//	@ApiOperation(value = "Import expenses and invoices")
//	@GetMapping(value="/expense/importall", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
//	public ResponseEntity importAll(@RequestParam(required=false) String staffId, 
//			@RequestParam(required=false)String expenseId,
//			@RequestParam(required=false) Integer status, 
//			@RequestParam(required=false) Date submittedDate) throws Exception{
//		
//		log.debug("***GET /expense/importall -> Start to export expense and invoice from Ali Cloud");
//		
//		SearchParams params = new SearchParams();
//		
//		params.setStaffId(staffId);
//		params.setExpenseId(expenseId);
//		params.setStatus(status);
//		params.setSubmittedDate(submittedDate);
//
//		return this.importAll(params);		
//	}
}
